package cc.linker.steplink.crm.service.impl;

import cc.linker.steplink.crm.commons.CallService;
import cc.linker.steplink.crm.commons.Constants;
import cc.linker.steplink.crm.commons.RandomCodeGenerator;
import cc.linker.steplink.crm.commons.constant.AppConstant;
import cc.linker.steplink.crm.commons.domain.WxUser;
import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.integral.IntegralRequest;
import cc.linker.steplink.crm.commons.model.SystemProperties;
import cc.linker.steplink.crm.commons.utils.AesEncryptUtils;
import cc.linker.steplink.crm.dao.*;
import cc.linker.steplink.crm.domain.*;
import cc.linker.steplink.crm.commons.utils.MD5;
import cc.linker.steplink.crm.merchanth5.commons.RequestFilter;
import cc.linker.steplink.crm.merchanth5.dao.MallBoomDao;
import cc.linker.steplink.crm.merchanth5.service.CustomerIntegralService;
import cc.linker.steplink.crm.merchanth5.service.MallBoomService;
import cc.linker.steplink.crm.merchanth5.service.MallService;
import cc.linker.steplink.crm.response.GlobalException;
import cc.linker.steplink.crm.service.PersonalService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class PersonalServiceImpl implements PersonalService {

    @Autowired
    private PersonalDao personalDao;

    @Autowired
    private PersonalCenterDao personalCenterDao;

    @Autowired
    private CustomerDao customerDao;

    @Autowired
    private CustomerInfoDao customerInfoDao;

    @Autowired
    private CustomerInfoWxDao customerInfoWxDao;

    @Autowired
    private ActionLogDao actionLogDao;
    @Autowired
    private CustomerBindDao customerBindDao;

    @Autowired
    private MallBoomDao mallBoomDao;

    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private HttpService httpService;
    @Autowired
    private MallService mallService;

    @Autowired
    private MallBoomService mallBoomService;

    @Autowired
    private  RequestFilter requestFilter;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private CustomerIntegralService customerIntegralService;

    private final static String wxAction = "getWeixinUserInfo";

    @Override
    @Deprecated
    public Map<String, String> getWxUserInfo(BindUserDto bindUser, HttpSession session) throws Exception {
        Map<String, String> returnInfo = new HashMap<>();
        int sourceChannel = 2;
        WxUserInfoDto wxUserInfoDto;
        Map<String, Object> params = new HashMap<>();
        params.put("action", wxAction);
        params.put("openid", bindUser.getOpenid());
        params.put("token", bindUser.getToken());
        //获取微信用户信息
        Object result = CallService.jsonPost(systemProperties.getWxpushurl(), JSON.toJSONString(params));
        //Map<String,Object> resultMap = JSON.parseObject(result.toString(),WxUserInfoDto.class);
        wxUserInfoDto = JSON.parseObject(result.toString(), WxUserInfoDto.class);//BeanMapUtils.mapToBean(resultMap,WxUserInfoDto.class);
        if (wxUserInfoDto.getErrcode().equals("200")) {
            //String customerId = personalDao.getCustomerIdByWxOpenId(bindUser.getGlobalOpenid());
            String orgId = customerBindDao.getOrgIdFromWeixinList( bindUser.getToken());
            String customerId = personalDao.getCustomerIdByOpenIdAndOrgId(bindUser.getOpenid(), orgId);

            //设置返回值
            WxUserInfo wxUserInfo = wxUserInfoDto.getData();
            if (wxUserInfo.getNickname() != null || wxUserInfo.getHeadimgurl() != null) {
                returnInfo.put("nickName", wxUserInfo.getNickname());
                returnInfo.put("headImgUrl", wxUserInfo.getHeadimgurl());
            } else {
                returnInfo = null;
            }
            Customer customer = new Customer();//客户信息
            customer.setCustomerName(wxUserInfo.getNickname());
            customer.setCustomerAvatar(wxUserInfo.getHeadimgurl());
            customer.setCustomerSourceChannel((byte) sourceChannel);
            customer.setWxGlobalOpenid(bindUser.getGlobalOpenid());
            customer.setWxToken(bindUser.getToken());
            customer.setWxOpenid(bindUser.getOpenid());
            customer.setCreateUser("H5");
            LOGGER.info("h5插入用户机构码[{}]", orgId);
            customer.setOrgId(orgId);

            CustomerInfo customerInfo = new CustomerInfo();//客户拓展信息
            customerInfo.setCustomerArea(wxUserInfo.getCountry() + wxUserInfo.getProvince() + wxUserInfo.getCity());
            CustomerInfoWx customerInfoWx = new CustomerInfoWx();//客户微信信息
            if (wxUserInfo.getSex() != null) {
                customerInfoWx.setWxGender(wxUserInfo.getSex().byteValue());
            }
            customerInfoWx.setWxGlobalOpenid(wxUserInfo.getOpenid());
            String area = "";
            if (!StringUtils.isEmpty(wxUserInfo.getCountry()) && !"null".equals(wxUserInfo.getCountry())) {
                area += wxUserInfo.getCountry();
            }
            area += "@";
            if (!StringUtils.isEmpty(wxUserInfo.getProvince()) && !"null".equals(wxUserInfo.getProvince())) {
                area += wxUserInfo.getProvince();
            }
            area += "@";
            if (!StringUtils.isEmpty(wxUserInfo.getCity()) && !"null".equals(wxUserInfo.getCity())) {
                area += wxUserInfo.getCity();
            }
            customerInfoWx.setWxAddress(area);
            customerInfoWx.setWxName(wxUserInfo.getNickname());
            customerInfoWx.setWxRemark(wxUserInfo.getRemark());
            customerInfoWx.setWxToken(bindUser.getToken());
            customerInfoWx.setWxOpenid(bindUser.getOpenid());
            customerInfoWx.setWxGlobalOpenid(bindUser.getGlobalOpenid());
            customerInfoWx.setWxAvatar(wxUserInfo.getHeadimgurl());
            if (customerId != null) {//已存在
                customer.setCustomerId(customerId);
                customerInfo.setCustomerId(customerId);
                customerInfoWx.setCustomerId(customerId);
                customerDao.updateByPrimaryKeySelective(customer);
                customerInfoDao.updateByCustomerIdSelective(customerInfo);
                customerInfoWxDao.updateByPrimaryKeySelective(customerInfoWx);
            } else {//不存在
                customer.setCustomerId(RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX));
                customerInfo.setCustomerId(customer.getCustomerId());
                customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
                customerInfoWx.setCustomerId(customer.getCustomerId());
                customerDao.insertCustomer(customer);
                customerInfoDao.insertSelective(customerInfo);
                customerInfoWxDao.insertSelective(customerInfoWx);
            }
            session.setAttribute("openid", bindUser.getOpenid());
            session.setAttribute("token", bindUser.getToken());
            session.setAttribute("nickname", wxUserInfo.getNickname());
            //记录用户行为
            Action action = new Action();
            action.setActionId(UUID.randomUUID().toString());
            action.setActionVisitTime(new Date());
            action.setOpenid(bindUser.getOpenid());
            action.setToken(bindUser.getToken());
            action.setCustomerId(customer.getCustomerId());
            actionLogDao.insertUpdateAction(action);
            ActionLog actionLog = new ActionLog(customer.getCustomerId(), UUID.randomUUID().toString(), action.getActionVisitTime(), 3, "访问个人H5");
            actionLogDao.insertUpdateActionLog(actionLog);
        } else {
            throw new Exception(wxUserInfoDto.getMsg());
        }
        return returnInfo;
    }

    @Override
    public WxUser saveWxH5User(String globalOpenid, String token, String openid) throws GlobalException {
        int sourceChannel = 2;
        Integer isVip = 0;
        if (!StringUtils.isEmpty(token) && StringUtils.isEmpty(openid) && !StringUtils.isEmpty(globalOpenid)) {
            // 未关注用户
            String orgId = customerBindDao.getOrgIdFromWeixinList(token);
            String customerId = personalDao.getCustomerIdByWxGlobalOpenIdAndOrgId(globalOpenid, orgId);
            Customer customer = new Customer();
            CustomerInfo customerInfo = new CustomerInfo();
            CustomerInfoWx customerInfoWx = new CustomerInfoWx();
            if (customerId == null) {//不存在
                customer.setWxToken(token);
                customer.setWxOpenid(globalOpenid);
                customer.setWxGlobalOpenid(globalOpenid);
                customer.setCustomerSourceChannel((byte) sourceChannel);
                customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX);
                customer.setCustomerId(customerId);
                customer.setOrgId(orgId);
                customer.setCreateUser("H5");
                customerInfo.setCustomerId(customerId);
                customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
                customerInfoWx.setCustomerId(customerId);
                customerInfoWx.setWxGlobalOpenid(globalOpenid);
                customerInfoWx.setWxToken(token);
                customerDao.insertCustomer(customer);
                customerInfoDao.insertSelective(customerInfo);
                customerInfoWxDao.insertSelective(customerInfoWx);
            }

            //记录用户行为
            Action action = new Action();
            action.setActionId(UUID.randomUUID().toString());
            action.setActionVisitTime(new Date());
            action.setToken(token);
            action.setCustomerId(customerId);
            actionLogDao.insertUpdateAction(action);
            ActionLog actionLog = new ActionLog(customerId, UUID.randomUUID().toString(), action.getActionVisitTime(), 3, "访问个人H5");
            actionLogDao.insertUpdateActionLog(actionLog);

            //查询绑定手机号业务关联用户
            String bindCustomerId = actionLogDao.getBindCustomer(orgId, globalOpenid);
            if (!StringUtils.isEmpty(bindCustomerId)) {
                customerId = bindCustomerId;
            }
            Integer payMode = mallService.getPayModeByOrgId(orgId);
            openid = globalOpenid;
//TODO            return new WxUser(globalOpenid, token, "", orgId, customerId, globalOpenid, payMode);
        }

        WxUserInfoDto wxUserInfoDto;
        Map<String, Object> params = new HashMap<>();
        params.put("action", wxAction);
        params.put("openid", openid);
//TODO        params.put("openid", globalOpenid);
        params.put("token", token);
        //获取微信用户信息
        String result = null;
        try {
            result = httpService.doPost(systemProperties.getWxpushurl(), JSON.toJSONString(params));
        } catch (URISyntaxException | IOException e) {
            LOGGER.error("调用微信矩阵信息失败");
            LOGGER.error("请求地址[{}]\n请求参数[{}]\n返回结果[{}]",
                    systemProperties.getWxpushurl(), params, result);
            throw GlobalException.build("获取用户信息异常");
        }
        if (StringUtils.isEmpty(result)) {
            throw GlobalException.build("获取用户信息异常");
        }
        try {
            wxUserInfoDto = JSON.parseObject(result, WxUserInfoDto.class);
        } catch (Exception e) {
            LOGGER.error("矩阵返回数据转为对象失败" + result, e);
            throw GlobalException.build("获取用户信息异常");
        }
        if ("200".equals(wxUserInfoDto.getErrcode())) {
            String customerId;
            String orgId = customerBindDao.getOrgIdFromWeixinList(token);
            customerId = personalDao.getCustomerIdByOpenIdAndOrgId(openid, orgId);
            if (StringUtils.isEmpty(customerId) && !StringUtils.isEmpty(globalOpenid)) {
                customerId = personalDao.getCustomerIdByWxGlobalOpenIdAndOrgId(globalOpenid, orgId);
            }
            // 设置返回值
            WxUserInfo wxUserInfo = wxUserInfoDto.getData();
            if (StringUtils.isEmpty(orgId)) {
                throw GlobalException.build("公众号暂未绑定");
            }
            LOGGER.info("h5插入用户机构码[{}]", orgId);

            customerId = this.updateUserInfo(wxUserInfoDto, openid, token, globalOpenid, orgId, customerId, wxUserInfo.getSubscribe());

            //查询绑定手机号业务关联用户
            String bindCustomerId = actionLogDao.getBindCustomer(orgId, globalOpenid);

            boolean addlogin = false;
            if (!StringUtils.isEmpty(bindCustomerId)) {
                customerId = bindCustomerId;
                addlogin = true;
            }

            String bindNickName = wxUserInfo.getNickname();
            String bindPhone = "";
            String sourceUserId = "";
            Map<String, Object> customerInfoByCustomerId = mallBoomDao.getCustomerInfoByCustomerId(customerId);
            if (null != customerInfoByCustomerId) {
                bindNickName = (String) customerInfoByCustomerId.get("customerName");
                bindPhone = (String) customerInfoByCustomerId.get("bindPhone");
                sourceUserId = (String) customerInfoByCustomerId.get("sourceUserId");
            }

            this.addLoginLog(addlogin, bindPhone, customerId, orgId, openid, token);

            Integer payMode = mallService.getPayModeByOrgId(orgId);
            return new WxUser(openid,"", token, bindNickName, orgId, customerId, globalOpenid, payMode,isVip,bindPhone,wxUserInfo.getHeadimgurl(),sourceUserId);
        } else {
            throw GlobalException.build(wxUserInfoDto.getMsg());
        }
    }


    @Override
    public WxUser getAllUser(String globalopenId, String token, String openId,String orgId,String customerId) {

        //查询绑定手机号业务关联用户
        String bindCustomerId = actionLogDao.getBindCustomer(orgId, openId);

        boolean addlogin = false;
        if (!StringUtils.isEmpty(bindCustomerId)) {
            customerId = bindCustomerId;
            addlogin = true;
        }
        String bindNickName ="";
        String bindPhone = "";
        String sourceUserId = "";
        String wxAvatar = "";
        Map<String, Object> customerInfoByCustomerId = mallBoomDao.getCustomerInfoByCustomerId(customerId);
        if (null != customerInfoByCustomerId) {
            bindNickName = (String) customerInfoByCustomerId.get("customerName");
            bindPhone = (String) customerInfoByCustomerId.get("bindPhone");
            sourceUserId = (String) customerInfoByCustomerId.get("sourceUserId");
            wxAvatar = (String) customerInfoByCustomerId.get("wxAvatar");
            openId = (String) customerInfoByCustomerId.get("openId");
            token = (String) customerInfoByCustomerId.get("token");
        }

        this.addLoginLog(addlogin, bindPhone, customerId, orgId, openId, token);

        Integer payMode = mallService.getPayModeByOrgId(orgId);
        return new WxUser(openId,"", token, bindNickName, orgId, customerId, globalopenId, payMode,0,bindPhone,wxAvatar,sourceUserId);
    }

    @Override
    public WxUser saveRouteUser(String openId, String wxappid, String orgId) {
        int sourceChannel = 8;
        Integer isVip = 0;
        String customerId = "";
        String globalOpenid =openId;
        if (!StringUtils.isEmpty(wxappid) && !StringUtils.isEmpty(openId)) {
            // 未关注用户
            customerId = personalDao.getCustomerIdByWxGlobalOpenIdAndOrgId(openId, orgId);
            Customer customer = new Customer();
            CustomerInfo customerInfo = new CustomerInfo();
            CustomerInfoWx customerInfoWx = new CustomerInfoWx();
            if (customerId == null) {//不存在
                customer.setWxToken(wxappid);
                customer.setWxOpenid(openId);
                customer.setWxGlobalOpenid(openId);
                customer.setCustomerSourceChannel((byte) sourceChannel);
                customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_ROUTE);
                customer.setCustomerId(customerId);
                customer.setOrgId(orgId);
                customer.setCreateUser("蓝色星球");
                customerInfo.setCustomerId(customerId);
                customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
                customerInfoWx.setCustomerId(customerId);
                customerInfoWx.setWxGlobalOpenid(openId);
                customerInfoWx.setWxToken(wxappid);
                customerDao.insertCustomer(customer);
                customerInfoDao.insertSelective(customerInfo);
                customerInfoWxDao.insertSelective(customerInfoWx);
            }

            //记录用户行为
            Action action = new Action();
            action.setActionId(UUID.randomUUID().toString());
            action.setActionVisitTime(new Date());
            action.setToken(wxappid);
            action.setCustomerId(customerId);
            actionLogDao.insertUpdateAction(action);
            ActionLog actionLog = new ActionLog(customerId, UUID.randomUUID().toString(), action.getActionVisitTime(), 3, "访问个人H5");
            actionLogDao.insertUpdateActionLog(actionLog);

        }
        Map<String, Object> params = new HashMap<>();
        params.put("action", wxAction);
        params.put("openid", openId);
        params.put("token", wxappid);
        //查询绑定手机号业务关联用户
        String bindCustomerId = actionLogDao.getBindCustomer(orgId, openId);

        boolean addlogin = false;
        if (!StringUtils.isEmpty(bindCustomerId)) {
            customerId = bindCustomerId;
            addlogin = true;
        }
        String bindNickName ="";
        String bindPhone = "";
        String sourceUserId = "";
        String wxAvatar = "";
        Map<String, Object> customerInfoByCustomerId = mallBoomDao.getCustomerInfoByCustomerId(customerId);
        if (null != customerInfoByCustomerId) {
            bindNickName = (String) customerInfoByCustomerId.get("customerName");
            bindPhone = (String) customerInfoByCustomerId.get("bindPhone");
            sourceUserId = (String) customerInfoByCustomerId.get("sourceUserId");
            wxAvatar = (String) customerInfoByCustomerId.get("wxAvatar");
            openId =  (String) customerInfoByCustomerId.get("openId");
        }

        this.addLoginLog(addlogin, bindPhone, customerId, orgId, openId, wxappid);

        Integer payMode = mallService.getPayModeByOrgId(orgId);
        return new WxUser(openId,"", wxappid, bindNickName, orgId, customerId, globalOpenid, payMode,isVip,bindPhone,wxAvatar,sourceUserId);

    }


    //通过用户ID修改支付openid
    @Override
    public void updatePayOpenIdByCustomerId(String customerId, String payOpenId){
        personalCenterDao.updatePayOpenIdByCustomerId(customerId,payOpenId);
    }

    @Override
    public Map<String, Object> getCustomerByCustomerId(String customerId) {
        return personalDao.getCustomerByCustomerId(customerId);
    }

    @Override
    public Map<String, Object> getCustomerByOpenId(String openId){
        return personalDao.getCustomerByPpenId(openId);
    }

    @Override
    public  Map<String,Object> getCustomerInfoBySourceUserId(String memberCode,String orgId){
        return  personalDao.getCustomerInfoBySourceUserId(memberCode,orgId);
    }

    @Override
    public Integer getIsVip(String customerId,String orgId) {
        Integer isVip = customerDao.getIsVip(customerId);
        if(isVip==null || isVip == 0){
            Map<String, Object> integralCustomerInfo = this.customerIntegralService.getIntegralCustomerInfo(customerId,orgId);
            int customerGrowthScore = Integer.valueOf(integralCustomerInfo.get("customerGrowthScore").toString());
            Integer isVipLevel = customerDao.getIsVipLevel(customerGrowthScore,orgId);
            if(isVipLevel!=null && isVipLevel>0){
                isVip=1;
            }
        }
        if(isVip==null || isVip == 0){
            isVip = customerDao.getIsVipByApp(customerId);
        }
        return  isVip==null?0:isVip;
    }


    @Async
    public void addLoginLog(boolean addlogin, String bindPhone, String customerId, String orgId, String openid, String token) {
        if (addlogin) {
            // 记录登录记录表  v1.11.16
            Map<String, Object> loginParam = new HashMap<>();
            loginParam.put("loginPhone", bindPhone);
            loginParam.put("loginCustomerId", customerId);
            loginParam.put("orgId", orgId);
            loginParam.put("openId", openid);
            loginParam.put("token", token);
            personalCenterDao.addLoginLog(loginParam);
        }
    }

    @Async
    public String updateUserInfo(WxUserInfoDto wxUserInfoDto, String openid, String token, String globalOpenid, String orgId, String customerId,Integer subscribe) {
        WxUserInfo wxUserInfo = wxUserInfoDto.getData();
        Customer customer = new Customer();//客户信息
        customer.setCustomerName(wxUserInfo.getNickname());
        customer.setCustomerAvatar(wxUserInfo.getHeadimgurl());
        customer.setCustomerSourceChannel((byte) 2);
        customer.setWxGlobalOpenid(globalOpenid);
        customer.setWxToken(token);
        customer.setWxOpenid(openid);
        customer.setCreateUser("H5");
        customer.setOrgId(orgId);
        customer.setSubscribe(subscribe);

        CustomerInfo customerInfo = new CustomerInfo();//客户拓展信息
        String area = "";
        if (!StringUtils.isEmpty(wxUserInfo.getCountry()) && !"null".equals(wxUserInfo.getCountry())) {
            area += wxUserInfo.getCountry();
        }
        area += "@";
        if (!StringUtils.isEmpty(wxUserInfo.getProvince()) && !"null".equals(wxUserInfo.getProvince())) {
            area += wxUserInfo.getProvince();
        }
        area += "@";
        if (!StringUtils.isEmpty(wxUserInfo.getCity()) && !"null".equals(wxUserInfo.getCity())) {
            area += wxUserInfo.getCity();
        }
        customerInfo.setCustomerArea(area);
        CustomerInfoWx customerInfoWx = new CustomerInfoWx();//客户微信信息
        if (wxUserInfo.getSex() != null) {
            customerInfoWx.setWxGender(wxUserInfo.getSex().byteValue());
        }
        customerInfoWx.setWxGlobalOpenid(wxUserInfo.getOpenid());
        customerInfoWx.setWxAddress(area);
        customerInfoWx.setWxName(wxUserInfo.getNickname());
        customerInfoWx.setWxRemark(wxUserInfo.getRemark());
        customerInfoWx.setWxToken(token);
        customerInfoWx.setWxOpenid(openid);
        customerInfoWx.setWxGlobalOpenid(globalOpenid);
        customerInfoWx.setWxAvatar(wxUserInfo.getHeadimgurl());
        String qr_scene_str = wxUserInfoDto.getData().getQr_scene_str();
        if (customerId != null) {//已存在
            // 上级id
            if(!StringUtils.isEmpty(qr_scene_str) && !customerId.equals(qr_scene_str)){
                String pid = customerDao.getPidByCid(customerId);
                if(StringUtils.isEmpty(pid)){
                    Customer pCustomer = customerDao.selectByPrimaryKey(qr_scene_str);
                    if (pCustomer != null && orgId.equals(pCustomer.getOrgId())) {
                        Map<String, String> tmpParam = new HashMap<>();
                        tmpParam.put("orgId", orgId);
                        tmpParam.put("customerId", qr_scene_str);
                        Integer promoterCount = mallBoomService.getPromoterCount(tmpParam);//判断推荐人是不是加盟代理
                        if (promoterCount > 0) {
                            customer.setParentCustomerId(qr_scene_str);
                            customer.setParentShareWay("scan");
                        }
                    }
                }
            }
            customer.setCustomerId(customerId);
            customerInfo.setCustomerId(customerId);
            customerInfoWx.setCustomerId(customerId);
            // 没有头像才更新
            Customer customer2 = customerDao.selectByPrimaryKey(customerId);
            String customerAvatar = customer2.getCustomerAvatar();
            if (StringUtils.isEmpty(customerAvatar)) {
                customerDao.updateByPrimaryKeySelective(customer);
            }
//            customerInfo.setCustomerArea(null);
//            customerInfo.setBirthday(null);
//            customerInfoDao.updateByCustomerIdSelective(customerInfo);

            Integer integer = customerInfoWxDao.countByCustomerId(customerId);
            if (integer != 0) {
                customerInfoWx.setWxAddress(null);
                customerInfoWx.setWxGender(null);
                customerInfoWxDao.updateByPrimaryKeySelective(customerInfoWx);
            } else {
                customerInfoWxDao.insertSelective(customerInfoWx);
            }
        } else {//不存在
            customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX);
            customer.setCustomerId(customerId);
            if (!StringUtils.isEmpty(qr_scene_str)) {
                Customer pCustomer = customerDao.selectByPrimaryKey(qr_scene_str);
                if (pCustomer != null && orgId.equals(pCustomer.getOrgId()) && !customerId.equals(qr_scene_str)) {
                    Map<String, String> tmpParam = new HashMap<>();
                    tmpParam.put("orgId", orgId);
                    tmpParam.put("customerId", qr_scene_str);
                    Integer promoterCount = mallBoomService.getPromoterCount(tmpParam);//判断推荐人是不是加盟代理
                    if (promoterCount > 0) {
                        customer.setParentCustomerId(qr_scene_str);
                        customer.setParentShareWay("scan");
                    }
                }
            }
            customerInfo.setCustomerId(customer.getCustomerId());
            customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
            customerInfoWx.setCustomerId(customer.getCustomerId());
            customerDao.insertCustomer(customer);
            customerInfoDao.insertSelective(customerInfo);
            customerInfoWxDao.insertSelective(customerInfoWx);
        }

        //记录用户行为
        Action action = new Action();
        action.setActionId(UUID.randomUUID().toString());
        action.setActionVisitTime(new Date());
        action.setOpenid(openid);
        action.setToken(token);
        action.setCustomerId(customerId);
        actionLogDao.insertUpdateAction(action);
        ActionLog actionLog = new ActionLog(customerId, UUID.randomUUID().toString(), action.getActionVisitTime(), 3, "访问个人H5");
        actionLogDao.insertUpdateActionLog(actionLog);

        return customerId;

    }

    @Override
    public Map<String, String> getWxUserInfo(HttpServletRequest request) throws Exception {
        WxUser wxUser = requestFilter.getWxUser(request);
        if (wxUser != null) {
            LOGGER.info("微信user不为空[{}]", wxUser);
            Map<String, String> returnInfo = new HashMap<>();
            String openid = wxUser.getOpenid();
            if (StringUtils.isEmpty(openid)) {
                // 未关注用户
                if (!StringUtils.isEmpty(wxUser.getGlobalOpenid())) {
                    returnInfo.put("nickName", "");
                    returnInfo.put("headImgUrl", "");
                    returnInfo.put("openid", "");
                    returnInfo.put("token", wxUser.getToken());
                    returnInfo.put("customerId", wxUser.getCustomerId());
                    returnInfo.put("subscribe", "0");
                    return returnInfo;
                }
                throw GlobalException.build("登录用户不存在或未关注");
            }
            CustomerInfoWx customerInfoWx = customerInfoWxDao.selectByPrimaryKey(
                    new CustomerInfoWxKey(wxUser.getOpenid(), wxUser.getToken()));
            if (customerInfoWx == null) {
                Customer customer = customerDao.selectByPrimaryKey(wxUser.getCustomerId());
                if (customer == null) {
                    throw GlobalException.build("登录用户不存在");
                }
                returnInfo.put("nickName", customer.getCustomerName());
                returnInfo.put("headImgUrl", customer.getCustomerAvatar());
            } else {
                returnInfo.put("nickName", customerInfoWx.getWxName());
                returnInfo.put("headImgUrl", customerInfoWx.getWxAvatar());
            }
            returnInfo.put("openid", wxUser.getOpenid());
            returnInfo.put("token", wxUser.getToken());
            returnInfo.put("customerId", wxUser.getCustomerId());

            WxUserInfoDto wxUserInfoDto;
            Map<String, Object> wxParams = new HashMap<>();
            wxParams.put("action", wxAction);
            wxParams.put("openid", wxUser.getOpenid());
            wxParams.put("token", wxUser.getToken());
            //获取微信用户信息
//            Object result = CallService.jsonPost(systemProperties.getWxpushurl(), JSON.toJSONString(wxParams));
            Map<String, String> postParam = new HashMap<>();
            postParam.put("Content-Type", "application/json;charset=UTF-8");
            String result = httpService.doPost(systemProperties.getWxpushurl(), JSON.toJSONString(wxParams), postParam);
            wxUserInfoDto = JSON.parseObject(result, WxUserInfoDto.class);
            String subscribe = "0";//Subscribe为0，不关注
            if (wxUserInfoDto.getErrcode().equals("200")) {
                //设置返回值
                WxUserInfo wxUserInfo = wxUserInfoDto.getData();
                subscribe = wxUserInfo.getSubscribe().toString();
            }
            returnInfo.put("subscribe", subscribe);

            return returnInfo;
        } else {
            throw GlobalException.build("登录用户不存在");
        }
    }

    @Override
    public Map<String, Object> getMissCustomerByOpenId(String openid) {
        return personalDao.getMissCustomerByOpenId(openid);
    }

    @Override
    public Map<String, Object> addUser(String token, String appCode) {
        // 获取当前机构id
        String orgId = personalDao.getOrgIdByToken(token, appCode);
        if (StringUtils.isEmpty(orgId)) {
            throw GlobalException.build("无效的token");
        }
        Integer payMode = personalDao.getPayModeByOrgId(orgId);
        String nickname = "岁月儒商";
        String createUser = "wap";
        String customerAvatar = "https://wxoss.linker.cc/Uploads/Picture/2020-02-19/5e4ceef66af58.png";
        // 判断当前机构是否存在游客账号
        Map<String, Object> map = new HashMap<>();
        map.put("nickname", nickname);
        map.put("orgId", orgId);
        map.put("createUser", createUser);
        Map<String, Object> temp = personalDao.getVisitorInfo(map);
        if (temp != null && !temp.isEmpty()) {
            temp.put("payMode", payMode);
            return temp;
        } else {
            String customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX);
            String openid = MD5.encode(customerId);

            Customer customer = new Customer();
            customer.setWxToken(token);
            customer.setCustomerSourceChannel((byte) 8);
            customer.setCustomerId(customerId);
            customer.setCustomerAvatar(customerAvatar);
            customer.setWxOpenid(openid);
            customer.setWxGlobalOpenid(openid);
            customer.setOrgId(orgId);
            customer.setCreateUser(createUser);
            customer.setCustomerName(nickname);
            customer.setSubscribe(1);
            customerDao.insertCustomer(customer);

            Map<String, Object> result = new HashMap<>();
            result.put("openid", openid);
            result.put("nickname", nickname);
            result.put("orgId", orgId);
            result.put("customerId", customerId);
            result.put("globalOpenid", openid);
            result.put("payMode", payMode);
            return result;
        }
    }

    @Override
    public Map<String, Object> getAppCustomerByAppUserId(String appUserId, String appId) {
        //查询账号手机关联表
        String customerId = personalDao.getCcustomerIdByApp(appUserId, appId);
        if(StringUtils.isEmpty(customerId)){
            return personalDao.getCustomerByAppUserId(appUserId, appId,AppConstant.DEFAULT_APP_ALIAS);
        }else {
            Integer isVip = personalDao.getIsVipByApp(appUserId, appId ,AppConstant.DEFAULT_APP_ALIAS);
            Map map = personalDao.getCustomerByCustomerId(customerId);
            if(map!=null){
                map.put("isVip",isVip==null?0:isVip);
            }
            return map;
        }

    }

    @Override
    public Map<String, Object> getAppCustomer(String appUserId, String appId) {
        Map map = this.callAppGetCustomer(appUserId, appId);
        String orgId = personalDao.getOrgIdByAppId(appId);
        Customer customer = new Customer();
        String customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX);
        customer.setCustomerId(customerId);
        customer.setCustomerName((String) map.get("nickName"));
        customer.setCustomerPhone((String) map.get("phone"));
        customer.setCustomerAvatar((String) map.get("icon"));
        customer.setCustomerSourceChannel((byte) 6);
        customer.setSubscribe(1);
        customer.setOrgId(orgId);
        customerDao.insertCustomer(customer);
        CustomerInfo customerInfo = new CustomerInfo();
        customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
        customerInfo.setCustomerId(customerId);
        customerInfoDao.insert(customerInfo);
        map.put("orgId", orgId);
        map.put("customerId",customerId);
        map.put("source",AppConstant.DEFAULT_APP_ALIAS);
        Integer isVip = 0;
        if(!StringUtils.isEmpty(map.get("isVip"))){
            isVip = Integer.valueOf(map.get("isVip").toString());
        }
        map.put("isVip",isVip);
        customerDao.insertAppCustomer(map);
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("customerId", customerId);
        resMap.put("orgId", orgId);
        resMap.put("customerName", customer.getCustomerName());
        resMap.put("cover", customer.getCustomerAvatar());
        return resMap;
    }

    /**
     * 调用app接口获取用户信息
     *
     * @param appUserId
     * @param appId
     * @return appId, appUserId, icon, nickName, phone
     */
    private Map callAppGetCustomer(String appUserId, String appId) {
        Map<String, Object> req = new HashMap<>();
        String s = appUserId + "_" + System.currentTimeMillis();
        // 加密
        try {
            s = AesEncryptUtils.encrypt(s);
        } catch (Exception e) {
            LOGGER.error("加密异常", e);
            throw GlobalException.build("加密异常");
        }
        req.put("appUserId", s);
        String url = personalDao.getAppUrlByAppId(appId);
        if (StringUtils.isEmpty(url)) {
            throw GlobalException.build("请先配置接口地址");
        }
        url += AppConstant.APP_USER_GET_BASE_USER;
        String result;
        try {
            result = httpService.doPost(url, req);
        } catch (URISyntaxException | IOException e) {
            LOGGER.error("app接口调用异常", e);
            throw GlobalException.build("app接口调用异常");
        }
        try {
            LOGGER.info("请求接口参数:", result);
            result = AesEncryptUtils.decrypt(result);
        } catch (Exception e) {
            LOGGER.error("解密异常", e);
            throw GlobalException.build("解密异常");
        }
        Map parse = (Map) JSON.parse(result);
        Integer rt = (Integer) parse.get("rt");
        if (rt == null || rt != 1) {
            LOGGER.info("callAppGetCustomer--------result：" + result);
            throw GlobalException.build("从app获取用户信息失败");
        }
        if (!parse.containsKey("object") || StringUtils.isEmpty(parse.get("object"))) {
            LOGGER.info("callAppGetCustomer--------result：" + result);
            throw GlobalException.build("从app获取用户信息失败");
        }
        Map map = (Map) parse.get("object");
        if (map.containsKey("sex") && !StringUtils.isEmpty(map.get("sex"))) {
            String sex = map.get("sex").toString();
            String gender = "2";
            if ("1".equals(sex)) {
                gender = "0";
            } else if ("0".equals(sex)) {
                gender = "1";
            }
            map.put("gender", gender);
        } else {
            map.put("gender", "1");
        }
        return map;
    }

//    @Async
    @Override
    public Integer updateAppCustomer(String appUserId, String appId) {
        Map map = this.callAppGetCustomer(appUserId, appId);
        Map<String, Object> customerMap = personalDao.getCustomerByAppUserId(appUserId, appId,AppConstant.DEFAULT_APP_ALIAS);
        String customerId = (String) customerMap.get("customerId");
        String orgId = "";
        if(!StringUtils.isEmpty(customerMap.get("orgId"))){
            orgId = customerMap.get("orgId").toString();
        }
        Customer customer = new Customer();
        customer.setCustomerId(customerId);
        customer.setCustomerName((String) map.get("nickName"));
        customer.setCustomerPhone((String) map.get("phone"));
        customer.setCustomerAvatar((String) map.get("icon"));
        customerDao.updateByPrimaryKeySelective(customer);
        map.put("source",AppConstant.DEFAULT_APP_ALIAS);
        Integer isVip = 0;
        if(!StringUtils.isEmpty(map.get("isVip"))){
            isVip = Integer.valueOf(map.get("isVip").toString());
        }
        map.put("isVip",isVip);
        customerDao.updateAppCustomer(map);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        WxUser wxUser = new WxUser(appUserId, appUserId, appId, customer.getCustomerName(), orgId,
                customerId, appUserId, payMode,isVip,customer.getCustomerPhone(),customer.getCustomerAvatar(),"");
        String key = MD5.encode(orgId + appUserId);
        //region 生成SH5TOKEN
        stringRedisTemplate.opsForValue().set("login:" + key, JSON.toJSONString(wxUser), 15, TimeUnit.MINUTES);
        return isVip;
    }
    /**
     * @Description: 第三方APP接入用户信息入库；
     * @Param:
     * @Return:
     * @Author: linker_zhang
     * @Date: 2020/5/21 14:21
     * @Version:
     **/

    public Map<String, Object> getAppCustomerByParams(Map map, String appId) {
        String orgId = personalDao.getOrgIdByAppId(appId);
        Customer customer = new Customer();
        String customerId = RandomCodeGenerator.getCustomerId(Constants.CUSTOMER_CODE_SOURCE_WX);
        customer.setCustomerId(customerId);
        customer.setCustomerName((String) map.get("nickName"));
        customer.setCustomerPhone((String) map.get("phone"));
        customer.setCustomerAvatar((String) map.get("icon"));
        customer.setCustomerSourceChannel((byte) 6);
        customer.setSubscribe(1);
        customer.setOrgId(orgId);
        customerDao.insertCustomer(customer);
        CustomerInfo customerInfo = new CustomerInfo();
        customerInfo.setCustomerInfoId(UUID.randomUUID().toString());
        customerInfo.setCustomerId(customerId);
        customerInfoDao.insert(customerInfo);
        map.put("orgId", orgId);
        map.put("customerId",customerId);
        customerDao.insertAppCustomer(map);
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("customerId", customerId);
        resMap.put("orgId", orgId);
        resMap.put("customerName", customer.getCustomerName());
        return resMap;
    }
    @Override
    public Map<String, Object> getAppCustomerByAppUserExpandInfo(String expandInfo, String appId) {
        expandInfo = URLDecoder.decode(expandInfo);
        LOGGER.info("getAppCustomerByAppUserExpandInfo-------",expandInfo);
        JSONObject jsonObject = JSON.parseObject(expandInfo);
        Map<String, Object> retMap = new HashMap<String, Object>();
        Map map = new HashMap();
        String appUserId =jsonObject.getString("equipment");
        String source =jsonObject.getString("source");
        String type = jsonObject.getString("type");
        if("0".equals(type)){
            //该设备信息是否有访问过，且未登录过app进行访问
            retMap = personalDao.getCustomerByAppUserId(appUserId, appId,source);
            if(retMap==null){
                //该设备是否已登录app进行访问
                retMap = personalDao.getCustomerByEquipment(appUserId, appId,source);
                if(retMap==null){
                    map.put("appUserId",appUserId);
                    map.put("appId",appId);
                    map.put("nickName","");
                    map.put("icon","");
                    map.put("phone","");
                    map.put("source",source);
                    map.put("isVip",0);
                    map.put("cover","");
                    retMap = this.getAppCustomerByParams(map,appId);
                }
            }
        }else{
            appUserId = jsonObject.getString("appUserId");
            source = jsonObject.getString("source");
            retMap = personalDao.getCustomerByAppUserId(appUserId, appId,source);
            map = jsonObject.getInnerMap();
            map.put("appId",appId);
            map.put("source",source);
            if(retMap==null){
                retMap = personalDao.getCustomerByAppUserId(jsonObject.getString("equipment"), appId,source);
                if(retMap==null){
                    map.put("isVip",0);
                    retMap = this.getAppCustomerByParams(map,appId);
                }else{
                    Customer customer = new Customer();
                    customer.setCustomerId(retMap.get("customerId").toString());
                    customer.setCustomerName((String) map.get("nickName"));
                    customer.setCustomerPhone((String) map.get("phone"));
                    customer.setCustomerAvatar((String) map.get("icon"));
                    map.put("isVip",retMap.get("isVip"));
                    customerDao.updateByPrimaryKeySelective(customer);
                    customerDao.updateAppCustomerByPhone(map);
                }
            }else{
                Customer customer = new Customer();
                customer.setCustomerId(retMap.get("customerId").toString());
                customer.setCustomerName((String) map.get("nickName"));
                customer.setCustomerPhone((String) map.get("phone"));
                customer.setCustomerAvatar((String) map.get("icon"));
                map.put("isVip",retMap.get("isVip"));
                customerDao.updateByPrimaryKeySelective(customer);
                customerDao.updateAppCustomer(map);
            }
        }

        retMap.put("appUserId",appUserId);
        return retMap;
    }

    @Override
    public String getOrgByToken(String token){
        String orgId = customerBindDao.getOrgIdFromWeixinList(token);
        return orgId;
    }
}
